module PrepareData where
import System.IO
import qualified Data.Map as Map
import qualified Data.Set as Set
--import Clustering.FuzzyCMeans (FuzzyCMeansParams, fuzzyCMeans)
import qualified GSL.LinearAlgebra.Vector as Vector

type FileSummary = Map.Map String Double
type BlameLine = (Int, String, String)
type Measure = String -> Double

parseBlameLine :: String -> BlameLine
parseBlameLine l = let 
	wrds = words l
	wrdsLen = length wrds 
	revision = read $ head wrds 
	author = wrds !! 1 
	content = if wrdsLen >=3 then wrds !! 2 else "" in 
		(revision, author, content)
--LineMeasure = (Int, String, Double)
--

group :: (a->a->Bool) -> [a] -> [[a]]
group f = g [] where
	g result [] = result
	g result (h:t) = g (newGroup:result) rest where
		newGroup = h:(filter (f h) t)
		rest = filter (not.f h) t

trFst (a,_,_) = a
trSnd (_,b,_) = b
trTrd (_,_,c) = c

extractFileSummary :: Measure -> [BlameLine] -> FileSummary
extractFileSummary meas lines = let 
	lineMeas (_,_,a) = meas a
	groupMeas = sum . (map lineMeas)
	measures = map (\(r, n, v) -> (r,n, meas v)) lines
	totalMeas = measureGroup measures
	groups = group (\(_,n1,_) (_,n2,_) -> n1 == n2) measures
	groupProbs = map (\g->(trSnd $ head g, (measureGroup g) / totalMeas)) groups
	in insertPairs Map.empty groupProbs where

		insertPairs :: Ord k =>Map.Map k a -> [(k,a)] -> Map.Map k a
		insertPairs result [] = result
		insertPairs result ((k,a):t) = insertPairs (Map.insert k a result) t

		measureGroup = sum . (map trTrd)


generateDataForClustering :: [FileSummary] -> [Vector.Vector Double]
generateDataForClustering fs = 
	let authOrdering =  Set.toList $ Set.unions $ map Map.keysSet fs in
		map (fileToVector authOrdering) fs where 
			fileToVector :: [String] -> FileSummary -> Vector.Vector Double
			fileToVector ao f = Vector.fromList $ (map (\k -> Map.findWithDefault 0 k f)) ao

--doPerformClustering :: [FilePath] -> IO [ClusteringResults]

{--
generateReports :: Map FilePath Content -> ([FilePath], ClusteringResults)


doExtractFileSummary :: FilePath -> IO FileSummary
doExtractFileSummary f = do 
	content <- readFile f
	let contentLines = lines content
	let blameLines = map parseBlameLine contentLines
	return extractFileSummary (\s -> length s) blameLines




doExtractFileSummaries :: [FilePath] -> IO [FileSummary]
doExtractFileSummaries = mapM doExtractFileSummary
	

doGenereateReport :: [(FilePath] -> IO (Map FilePath ClusteringResults)
-}
